package com.gimi.cloud.bbp.client.controller.userInfo;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gimi.cloud.bbp.client.service.UserService;
import com.gimi.cloud.bbp.client.service.bank.BankService;
import com.gimi.cloud.bbp.client.service.userInfo.UserInfoService;
import com.gimi.cloud.bbp.common.constant.RedisKeyConstant;
import com.gimi.cloud.bbp.common.enums.ResponseCodeEnum;
import com.gimi.cloud.bbp.common.exception.MsgException;
import com.gimi.cloud.bbp.common.utils.JsonUtil;
import com.gimi.cloud.bbp.common.utils.StringUtil;
import com.gimi.cloud.bbp.common.utils.base64.Base64Util;
import com.gimi.cloud.bbp.common.utils.oss.AliOSSUtil;
import com.gimi.cloud.bbp.common.utils.reqhead.Response;
import com.gimi.cloud.bbp.common.utils.reqhead.Util;
import com.gimi.cloud.bbp.commonService.redis.RedisService;
import com.gimi.cloud.bbp.dao.dao.sys.SysConfigDao;
import com.gimi.cloud.bbp.dto.bank.BankDTO;
import com.gimi.cloud.bbp.dto.base.BaseAppDTO;
import com.gimi.cloud.bbp.dto.core.TongDunDTO;
import com.gimi.cloud.bbp.dto.lianlian.PayCashBean;
import com.gimi.cloud.bbp.dto.userInfo.PhotoFileUploadDTO;
import com.gimi.cloud.bbp.dto.userInfo.RdUserInfoDTO;
import com.gimi.cloud.bbp.entity.bank.Bank;
import com.gimi.cloud.bbp.entity.user.User;
import com.gimi.cloud.bbp.entity.userInfo.RdUserInfoEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.*;

/**
 * 用户详细信息管理
 * 
 * @author chendi
 * @date 2017年12月27日
 */
@RestController
@RequestMapping(value = "userInfo")
public class UserInfoController {
	private static Logger log = LoggerFactory.getLogger(UserInfoController.class);
	private UserInfoService userInfoService;
	private UserService userService;
	private BankService bankService;
	private SysConfigDao sysConfigDao;
	private RedisService redisService;

	@Autowired
	public UserInfoController(UserInfoService userInfoService, UserService userService, BankService bankService, SysConfigDao sysConfigDao, RedisService redisService) {
		this.userInfoService = userInfoService;
		this.userService = userService;
		this.bankService = bankService;
		this.sysConfigDao = sysConfigDao;
		this.redisService = redisService;
	}

	/**
	 * 新添加user详细信息
	 * 
	 * @param userInfoDTO
	 * @param response
	 */
	@RequestMapping(value = "/add")
	public void addUserInfo(@RequestBody RdUserInfoDTO userInfoDTO, HttpServletResponse response) {
		Response resp = new Response();
		RdUserInfoEntity infoEntity = new RdUserInfoEntity();
		BeanUtils.copyProperties(userInfoDTO, infoEntity);
		userInfoService.addUserInfo(infoEntity);
		resp.setResponseCode(ResponseCodeEnum.SUCCESSED);
		Util.sendResponse(JsonUtil.toJson(resp), response);
	}

	/**
	 * 根据user_id查询user详细信息
	 */
	@RequestMapping(value = "/single")
	public void single(@RequestBody RdUserInfoDTO userInfoDTO, HttpServletResponse response) {
		Response resp = new Response();
		RdUserInfoDTO data = userInfoService.getUserInfoSingle(userInfoDTO);
		resp.setRes_data(data);
		resp.setResponseCode(ResponseCodeEnum.SUCCESSED);
		Util.sendResponse(JsonUtil.toJson(resp), response);
	}

	/**
	 * 更新user信息
	 * 
	 * @param userInfoDTO
	 * @param response
	 */
	@RequestMapping(value = "/update")
	public void updateUserInfo(@RequestBody RdUserInfoDTO userInfoDTO, HttpServletResponse response) {
		Response resp = new Response();
		userInfoService.updateUserInfo(userInfoDTO);
		resp.setResponseCode(ResponseCodeEnum.SUCCESSED,"保存成功");
		Util.sendResponse(JsonUtil.toJson(resp), response);
	}

	/**
	 * App端更新user信息
	 * 
	 * @param requestDataMap
	 * @param response
	 */
	@RequestMapping(value = "/updateAppUserIdinfo")
	public void updateAppUserIdinfo(@RequestBody Map<String, String> requestDataMap, HttpServletResponse response)
			throws Exception {
		log.info("身份证更新，请求参数requestDataMap:" + requestDataMap);
		Response resp = new Response();
		User userBean = userService.getUserById(Integer.parseInt(requestDataMap.get("userId")));
		if (userBean == null) {
			resp.setResponseCode(ResponseCodeEnum.ERR_USER_INVALID);
			resp.setRes_msg("用户不存在");
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return;
		}
		String cardId = requestDataMap.get("cardId");// 身份证号

		// 判断身份证是否存在
		RdUserInfoDTO exits = userInfoService.getUserBycardId(cardId);
		if (exits != null) { // 如果存在，且用户id与当前id不一致
			if (userBean.getUserId().intValue() != exits.getUserId().intValue()) {
				resp.setResponseCode(ResponseCodeEnum.ERR_REALNAME_NOT_AUTH);
				Util.sendResponse(JsonUtil.toJson(resp), response);
				return;
			}
		}

		RdUserInfoEntity userIdinfo = userInfoService.getUserInfoByUserId(userBean.getUserId());
		/**
		 * 若图片有一张保存失败则判断为失败
		 */
		String idcard_front_pic = userIdinfo.getCardFront();
		String idcard_back_pic = userIdinfo.getCardBack();
		String avatar = userIdinfo.getAvatar();
		if (StringUtil.isBlank(idcard_front_pic) || StringUtil.isBlank(idcard_back_pic) || StringUtil.isBlank(avatar)) {
			resp.setResponseCode(ResponseCodeEnum.ERR_CARDPIC_NOT_EXIST);
			resp.setRes_msg("请拍摄身份证正（反）面照片");
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return;
		}

		userIdinfo.setCardId(cardId);
		userIdinfo.setRealName(requestDataMap.get("realName"));
		userIdinfo.setSex(Integer.parseInt(requestDataMap.get("sex")));
		userIdinfo.setNationality(requestDataMap.get("nationality"));
		userIdinfo.setBirthday(Integer.parseInt(requestDataMap.get("birthday")));
		userIdinfo.setAddress(requestDataMap.get("address"));
		userIdinfo.setPolice(requestDataMap.get("police"));
		userIdinfo.setValidDate(requestDataMap.get("validDate"));
		userIdinfo.setHomeAddress(requestDataMap.get("homeAddress"));

		userIdinfo.setAddTime(new Date());
		userInfoService.updateUserInfo(userIdinfo);

		TongDunDTO tongDunDTO = new TongDunDTO();
		tongDunDTO.setId_number(cardId);
		tongDunDTO.setMobile(userIdinfo.getMobilePhone());
		tongDunDTO.setName(userIdinfo.getRealName());
		tongDunDTO.setUserId(userIdinfo.getUserId());

		// 修改认证状态
		resp.setResponseCode(ResponseCodeEnum.SUCCESSED);
		Util.sendResponse(JsonUtil.toJson(resp), response);
	}

	@RequestMapping(value = "/photoFileUpload")
	public void fileUpload(HttpServletRequest request, HttpServletResponse response,@RequestBody PhotoFileUploadDTO fileUpload) throws Exception {
		String url = null;
		Integer userId = fileUpload.getUserId();
		User user = userService.getUserById(userId);
		if (user==null) {
			throw new MsgException(ResponseCodeEnum.ERR_USER_INVALID);
		}
		InputStream inputStream = null;
		try {
			inputStream = Base64Util.dencoderToInputStream(fileUpload.getFilebase());
		} catch (Exception e) {
			log.error("base64解码错误");
			e.printStackTrace();
			throw new MsgException(ResponseCodeEnum.SERVICE_ERROR,"base64解码错误");
		}
		
		String tempUrl = null;
		StringBuffer filename = new StringBuffer().append("userid").append(userId).append("_").append(new Random().nextInt(1000))
				.append(".").append(fileUpload.getSuffix());
		try {
			url = AliOSSUtil.uploadFile(inputStream, "user/headportrait", filename.toString());
			tempUrl = AliOSSUtil.getFileUrl(url,new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 365 * 100));
		} catch (Exception e) {
			e.printStackTrace();
			log.error("用户头像上传阿里云失败");
			throw new MsgException(ResponseCodeEnum.SERVICE_ERROR);
		}

		RdUserInfoEntity rdUserInfo = userInfoService.getUserInfoByUserId(user.getUserId());
		rdUserInfo.setPhoto(url);
		userInfoService.updateUserInfo(rdUserInfo);

		Response resp = new Response();
		Map<String, String> data = new HashMap<>();
		data.put("url", tempUrl);
		resp.setRes_data(data);
		resp.setResponseCode(ResponseCodeEnum.SUCCESSED);
		Util.sendResponse(JsonUtil.toJson(resp), response);
	}

	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/uploadCardPhoto")
	public void uploadCardPhoto(HttpServletRequest request, HttpServletResponse response) throws Exception {
		Response resp = new Response();
		String url = "";
		StandardMultipartHttpServletRequest multipartHttpServletRequest = (StandardMultipartHttpServletRequest) request;
		MultiValueMap<String, MultipartFile> multipartFiles = multipartHttpServletRequest.getMultiFileMap();
		Enumeration<String> pNames = request.getParameterNames();

		String type = null;
		String userId = null;
		while (pNames.hasMoreElements()) {
			String name = (String) pNames.nextElement();
			String value = request.getParameter(name);
			if ("type".equals(name)) {
				type = value.replaceAll("\\[", "").replaceAll("\\]", "");
			} else if ("userId".equals(name)) {
				userId = value.replaceAll("\\[", "").replaceAll("\\]", "");
			}
		}

		if (StringUtil.isBlank(type) || StringUtil.isBlank(userId)) {
			resp.setResponseCode(ResponseCodeEnum.PARAMETER_ERROR);
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return;
		}
		User user = userService.getUserById(Integer.valueOf(userId));
		for (Object entry : multipartFiles.entrySet()) {
			LinkedList<MultipartFile> lists = ((Map.Entry<String, LinkedList<MultipartFile>>) entry).getValue();
			for (MultipartFile file : lists) {
				InputStream is = file.getInputStream();
				String dirPath = "userInfo/" + user.getMobilePhone();
				String[] originalFilenames = file.getOriginalFilename().split("\\.");
				String fileName = type + "." + originalFilenames[originalFilenames.length - 1];
				String result = AliOSSUtil.uploadFileCanBeOverLoad(is, dirPath, fileName);
				String tempUrl = AliOSSUtil.getFileUrl(result,
						new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 365 * 100));
				System.out.println("==========>上传结果：" + url);
				url += tempUrl;
			}
		}

		// 上传成功，则根据mobilePhone找到userInfo，然后保存对应的地址
		RdUserInfoEntity rdUserInfoDTO = userInfoService.getUserInfoByUserId(user.getUserId());
		switch (type) {
		case "front":// 身份证正面
			rdUserInfoDTO.setCardFront(url);
			break;
		case "back":// 身份反面
			rdUserInfoDTO.setCardBack(url);
			break;
		case "avatar":// 身份证小头像
			rdUserInfoDTO.setAvatar(url);
			break;
		case "photo":// 头像
			rdUserInfoDTO.setPhoto(url);
			break;
		case "hand":// 人脸识别的照片
			rdUserInfoDTO.setCardHand(url);
			break;
		default:
			rdUserInfoDTO.setCardHand(url);
			break;
		}
		userInfoService.updateUserInfo(rdUserInfoDTO);

		Map<String, String> data = new HashMap<>();
		data.put("url", url.equals("") ? url : url.substring(1));
		resp.setRes_data(data);
		resp.setResponseCode(ResponseCodeEnum.SUCCESSED);
		Util.sendResponse(JsonUtil.toJson(resp), response);
	}

	/**
	 * 查询user信息
	 * 
	 * @param userInfoDTO
	 * @param response
	 */
	@RequestMapping(value = "/getUserInfo")
	public void getUserInfo(@RequestBody RdUserInfoDTO userInfoDTO, HttpServletResponse response) {
		log.info("身份证查询，请求参数requestDataMap:" + userInfoDTO);
		Response resp = new Response();
		User userBean = userService.getUserById(userInfoDTO.getUserId());
		if (userBean == null) {
			resp.setResponseCode(ResponseCodeEnum.ERR_USER_INVALID);
			resp.setRes_msg("用户不存在");
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return;
		}
		RdUserInfoEntity userIdinfo = userInfoService.getUserInfoByUserId(userInfoDTO.getUserId());
		if (userIdinfo == null) {
			userIdinfo = new RdUserInfoEntity();
			BeanUtils.copyProperties(userBean, userIdinfo);
			userInfoService.addUserInfo(userIdinfo);
		}
		//userIdinfo.setPhoto(AliOSSUtil.getFileUrl(userIdinfo.getPhoto(), 30*24*60*60));
		Map<String, Object> map = new HashMap<>();
		userBean.setPwd(null);
		map.put("user", userBean);
		map.put("userIdinfo", userIdinfo);
		resp.setRes_data(map);
		resp.setResponseCode(ResponseCodeEnum.SUCCESSED);
		Util.sendResponse(JsonUtil.toJSONStringWithDateFormatYYYYMMDDHHMMSS(resp), response);
	}

	/**
	 * App端更新bank信息
	 * 
	 * @param bankDTO
	 * @param response
	 */
	@RequestMapping(value = "/updateUserbankcard")
	public void updateUserbankcard(@RequestBody BankDTO bankDTO, HttpServletResponse response) throws Exception {
		log.info("银行卡更新，请求参数requestDataMap:" + bankDTO);
		Response resp = new Response();
		User userBean = userService.getUserById(bankDTO.getUserId());
		if (userBean == null) {
			resp.setResponseCode(ResponseCodeEnum.ERR_USER_INVALID);
			resp.setRes_msg("用户不存在");
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return;
		}
		String cardNo = bankDTO.getCardNo();// 银行卡号

		/** 不支持的银行卡号，主要是邮政的 */
		boolean flag = false;

		String config = sysConfigDao.getConfigByKey("notBankCard");
		log.info("不支持的银行卡号，请求参数：" + config);

		List<String> notBankCardResults = Arrays.asList(config.split(","));
		// 如果满足在黑名单中的银行卡那么久返回不支持
		for (String string : notBankCardResults) {
			if (cardNo.startsWith(string)) {
				flag = true;
				break;
			}
		}
		if (flag) {
			throw new MsgException(ResponseCodeEnum.BANK_ERROR);
		}

		log.info("银行卡更新接口.........开始查询连连.........");

		/**
		 * -----TODO 此时如果放开此连连查询接口，则会报{"ret_code":"1008","ret_msg":"商户请求IP错误"} , 所以先注释了
		 */
		// Map<String, String> map = bankService.bankcardQuery(cardNo);
		// if(StringUtil.isBlank(map.get("bank_name"))){
		// throw new MsgException(ResponseCodeEnum.MEMORY_CARD);
		// }
		// String bank_name = map.get("bank_name").replaceAll("\\(|\\)", "");
		// String bank_code = map.get("bank_code");
		// String card_type = map.get("card_type");
		//
		// logger.info("银行卡更新接口.........结束查询连连.........");
		// if (!"2".equals(card_type)) {
		// throw new MsgException(ResponseCodeEnum.MEMORY_CARD);
		// }
		// // 判断是否支持该银行
		// boolean useable = bankService.useable(bank_code);
		// if (!useable) {
		// throw new MsgException(ResponseCodeEnum.BANK_ERROR);
		// }

		/**
		 * -----TODO 此时如果放开此连连查询接口，则会报{"ret_code":"1008","ret_msg":"商户请求IP错误"} , 所以先注释了
		 */

		// 根据userId找到Bank，没有则新增
		Bank bank = bankService.getBankByUserId(bankDTO.getUserId());
		boolean temp = false;
		if (bank == null) {
			bank = new Bank();
			bank.setUserId(bankDTO.getUserId());
			bank.setAddTime(new Date());
			temp = true;
		} else {
			bank.setUpdateTime(new Date());
		}
		bank.setCardNo(bankDTO.getCardNo());
		bank.setCity(bankDTO.getCity());
		bank.setCounty(bankDTO.getCounty());
		bank.setNation(bankDTO.getNation());
		bank.setPhone(bankDTO.getPhone());
		bank.setProvince(bankDTO.getProvince());
		bank.setSubBankName(bankDTO.getSubBankName());
		// TODO 所属银行的id待定
		// bank.setBiId();

		if (temp) {
			bankService.insert(bank);
		} else {
			bankService.update(bank);
		}

		// 修改认证状态
		resp.setResponseCode(ResponseCodeEnum.SUCCESSED);
		Util.sendResponse(JsonUtil.toJson(resp), response);
	}

	/**
	 * App端更新bank信息
	 * 
	 * @param bankDTO
	 * @param response
	 */
	@RequestMapping(value = "/bankCardSign")
	public void bankCardSign(@RequestBody BankDTO bankDTO, HttpServletResponse response) throws Exception {
		log.info("银行卡更新，请求参数requestDataMap:" + bankDTO);
		Map<String, Object> data = new HashMap<String, Object>();
		Response resp = new Response();
		User userBean = userService.getUserById(bankDTO.getUserId());
		if (userBean == null) {
			resp.setResponseCode(ResponseCodeEnum.ERR_USER_INVALID);
			resp.setRes_msg("用户不存在");
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return;
		}
		String cardNo = bankDTO.getCardNo();// 银行卡号

		// 判断银行卡号是否存在
		Bank exits = bankService.getBankBycardNo(cardNo);
		if (exits != null) { // 如果存在，且用户id与当前id不一致
			if (userBean.getUserId().intValue() != exits.getUserId().intValue()) {
				resp.setResponseCode(ResponseCodeEnum.ERR_BANKNO_NOT_AUTH);
				Util.sendResponse(JsonUtil.toJson(resp), response);
				return;
			}
		}

		RdUserInfoEntity rdUserInfo = userInfoService.getUserInfoByUserId(userBean.getUserId());
		if (rdUserInfo == null) {
			resp.setResponseCode(ResponseCodeEnum.ERR_CARDID_NOT_AUTH);
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return;
		}
		// 此处进行拼接json
		PayCashBean result = bankService.bankCardSign(rdUserInfo, cardNo);

		// 修改认证状态
		data.put("reqJson", result);
		resp.setRes_data(data);
		resp.setResponseCode(ResponseCodeEnum.SUCCESSED);
		Util.sendResponse(JsonUtil.toJson(resp), response);
	}

	/**
	 * 查询bank信息
	 * 
	 * @param userInfoDTO
	 * @param response
	 */
	@RequestMapping(value = "/getUserBankcard")
	public void getUserBankcard(@RequestBody RdUserInfoDTO userInfoDTO, HttpServletResponse response) {
		log.info("身份证查询，请求参数requestDataMap:" + userInfoDTO);
		Response resp = new Response();
		User userBean = userService.getUserById(userInfoDTO.getUserId());
		if (userBean == null) {
			resp.setResponseCode(ResponseCodeEnum.ERR_USER_INVALID);
			resp.setRes_msg("用户不存在");
			Util.sendResponse(JsonUtil.toJson(resp), response);
			return;
		}
		BankDTO bank = bankService.getBankDTOByUserId(userInfoDTO.getUserId());
		RdUserInfoEntity info = userInfoService.getUserInfoByUserId(userInfoDTO.getUserId());
		if (bank != null) {
			if (info != null) {
				bank.setUserName(info.getRealName());
			}
		}
		resp.setRes_data(bank);
		resp.setResponseCode(ResponseCodeEnum.SUCCESSED);
		Util.sendResponse(JsonUtil.toJSONStringWithDateFormatYYYYMMDDHHMMSS(resp), response);
	}
	
	/**
	 * 修改用户非关键信息
	 * @param userInfoDTO
	 * @param response
	 */
	@RequestMapping(value = "/updateUnimportantUserinfo")
	public void updateUnimportantUserinfo(@RequestBody RdUserInfoDTO userInfoDTO, HttpServletResponse response) {
		Util.sendResponse(JSON.toJSONString(userInfoService.updateUnimportantUserinfo(userInfoDTO)), response);
	}

	/**
	 * 获取协议信息
	 * @param request
	 * @param response
	 * @param dto
	 */
	@RequestMapping(value = "/getAgreement")
	public void getAgreement(HttpServletRequest request, HttpServletResponse response, @RequestBody BaseAppDTO dto){
		Response resp = new Response();
		JSONObject agreementPaths = redisService.getJSONObjectConfigByKey(RedisKeyConstant.CONFIG_KEY_APP_AGREEMENT_PATH_INFO);
		Map<String,String> resData = new HashMap<>();
		resData.put("commonQuestion",agreementPaths.getString("commonQuestion"));
		resData.put("registerAgreement",agreementPaths.getString("register_agreement"));
		resp.setRes_data(resData);
		resp.setResponseCode(ResponseCodeEnum.SUCCESSED,"获取成功");
		Util.sendResponse(JsonUtil.toJson(resp), response);
	}
}
